import functools
import os
import json
import time
import datetime
import traceback
import re
import os  # 补充缺失的导入


class Logger:
    def __init__(self, log_dir=None, log_level='INFO',file_prefix='eltagent'):
        """
        初始化日志工具
        :param log_dir: 日志文件存放目录
        :param log_level: 日志级别，默认为INFO，可选值：DEBUG, INFO, WARNING, ERROR
        """
        current_file_dir = os.path.dirname(os.path.abspath(__file__))
        log_dir = os.path.join(current_file_dir, '..', 'logs')
        log_dir = os.path.normpath(log_dir)
        # 创建日志目录（如果不存在）
        self.log_dir = log_dir
        self.file_prefix = file_prefix
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)

        # 设置日志级别
        self.log_levels = {'DEBUG': 1, 'INFO': 2, 'WARNING': 3, 'ERROR': 4}
        self.set_level(log_level)


        # 日志文件名（按天生成）
        self.log_file = self._get_log_filename()

    def _get_log_filename(self):
        """生成日志文件名，格式：YYYY-MM-DD.log"""
        today = datetime.datetime.now().strftime('%Y%m%d')
        return os.path.join(self.log_dir, f'{self.file_prefix}-{today}.log')

    def set_level(self, level):
        """设置日志级别"""
        if level in self.log_levels:
            self.current_level = self.log_levels[level]
        else:
            raise ValueError(f"无效的日志级别: {level}，可选值：DEBUG, INFO, WARNING, ERROR")

    def _write_log(self, level, message):
        """写入日志到文件和控制台"""
        # 检查是否需要生成新的日志文件（跨天时）
        current_file = self._get_log_filename()
        if current_file != self.log_file:
            self.log_file = current_file

        # 获取当前时间戳
        timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]  # 保留毫秒

        # 控制台输出（保持原格式）
        console_message = f'[{timestamp}] [{level}] {message}\n'
        # 根据日志级别设置不同颜色
        if level == 'DEBUG':
            print(f'\033[94m{console_message}\033[0m', end='')  # 蓝色
        elif level == 'INFO':
            print(f'\033[92m{console_message}\033[0m', end='')   # 绿色
        elif level == 'WARNING':
            print(f'\033[93m{console_message}\033[0m', end='') # 黄色
        elif level == 'ERROR':
            print(f'\033[91m{console_message}\033[0m', end='')  # 红色

        # 文件输出（JSON格式）
        log_data = {
            'timestamp': timestamp,
            'level': level,
            'message': message
        }

        # 对于错误级别，添加堆栈信息
        if level == 'ERROR':
            log_data['traceback'] = traceback.format_exc()

        try:
            with open(self.log_file, 'a', encoding='utf-8') as f:
                # 写入JSON字符串，每条日志占一行
                f.write(json.dumps(log_data, ensure_ascii=False) + '\n')
        except Exception as e:
            print(f'\033[91m写入日志文件失败: {str(e)}\033[0m')

    def debug(self, message):
        """输出DEBUG级别的日志"""
        if self.current_level <= self.log_levels['DEBUG']:
            self._write_log('DEBUG', message)

    def info(self, message):
        """输出INFO级别的日志"""
        if self.current_level <= self.log_levels['INFO']:
            self._write_log('INFO', message)

    def warning(self, message):
        """输出WARNING级别的日志"""
        if self.current_level <= self.log_levels['WARNING']:
            self._write_log('WARNING', message)

    def error(self, message):
        """输出ERROR级别的日志"""
        if self.current_level <= self.log_levels['ERROR']:
            self._write_log('ERROR', message)


class UserLogger:
    def __init__(self, log_dir='../logs/user', log_level='INFO',file_prefix=''):
        """
        初始化日志工具
        :param log_dir: 日志文件存放目录
        :param log_level: 日志级别，默认为INFO，可选值：DEBUG, INFO, WARNING, ERROR
        """

        current_file_dir = os.path.dirname(os.path.abspath(__file__))
        log_dir = os.path.join(current_file_dir, '..', 'logs/user')
        log_dir = os.path.normpath(log_dir)
        # 创建日志目录（如果不存在）
        self.log_dir = log_dir
        self.file_prefix = file_prefix
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)

        # 设置日志级别
        self.log_levels = {'DEBUG': 1, 'INFO': 2, 'WARNING': 3, 'ERROR': 4}
        # 补充日志级别设置
        self.log_level = self.log_levels.get(log_level.upper(), 2)
        self.file_line_numbers = {}



    def _get_log_filename(self,prefix):
        """生成日志文件名，格式：YYYY-MM-DD.log"""
        today = datetime.datetime.now().strftime('%Y%m%d')
        return os.path.join(self.log_dir, f'{prefix}-{today}.log')
     # 获取当前要写入的行号（日志文件中的行号）

    def _get_current_line_number(self, file_path):
        """获取日志文件当前的行号（即新写入行的行号）"""
        # 如果是新文件或首次记录，从1开始
        if file_path not in self.file_line_numbers:
            # 检查文件是否已存在，如果存在则计算当前行数
            if os.path.exists(file_path):
                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        line_count = sum(1 for _ in f)
                        self.file_line_numbers[file_path] = line_count + 1
                except Exception as e:
                    print(f'\033[91m获取文件行数失败: {str(e)}\033[0m')
                    self.file_line_numbers[file_path] = 1
            else:
                self.file_line_numbers[file_path] = 1

        current_line = self.file_line_numbers[file_path]
        # 行号递增，准备下一次写入
        self.file_line_numbers[file_path] += 1
        return current_line

    def set_prefix(self, prefix):
        """设置日志前缀"""  # 修正方法描述
        self.file_prefix = prefix

    def info(self, prefix, message):
        """输出INFO级别的日志"""
        # 修复：移除多余的self参数
        self._write_log(prefix, message)

    def _write_log(self, prefix, message):
        """写入日志到文件和控制台"""
        # 检查是否需要生成新的日志文件（跨天时）
        current_file = self._get_log_filename(prefix)

        try:
            with open(current_file, 'a', encoding='utf-8') as f:
                f.write(message + '\n')
                f.flush()  # 强制刷新缓冲区，立即写入磁盘
        except Exception as e:
            print(f'\033[91m写入日志文件失败: {str(e)}\033[0m')

# 创建一个默认的日志实例，方便其他模块直接导入使用
logger = Logger()
user_logger = UserLogger()

def node_logger(func):

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        args_str = ", ".join(repr(arg) for arg in args)
        kwargs_str = ", ".join(f"{k}={v!r}" for k, v in kwargs.items())

        all_args = []
        if args_str:
            all_args.append(args_str)
        if kwargs_str:
            all_args.append(kwargs_str)
        params_str = ", ".join(all_args)

        start_time = time.perf_counter()
        logger.info(f"这是@node_logger打印的日志：开始调用节点函数: {func.__name__}，参数: ({params_str})")

        try:
            result = func(*args, **kwargs)
            elapsed_time = time.perf_counter() - start_time
            logger.info(f"这是@node_logger打印的日志：节点函数 {func.__name__} 调用完成，耗时: {elapsed_time:.6f}秒")
            return result
        except Exception as e:
            elapsed_time = time.perf_counter() - start_time
            logger.error(f"节点函数 {func.__name__} 调用出错: {str(e)}，参数: ({params_str})，耗时: {elapsed_time:.6f}秒")
            raise

    return wrapper